package command

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"time"

	"gitee.com/xiaoyutab/sql-backups/config"
	"gitee.com/xiaoyutab/sql-backups/model"
	"gitee.com/xiaoyutab/xgotool/xstring"
	"github.com/glebarez/sqlite"
	"gorm.io/gorm"
)

// 还原数据库操作
func up(help bool) string {
	if help {
		return "数据库还原操作，从sqlite数据库 xxx_*.db 中进行还原，根据配置还原到原数据库中"
	}
	fmt.Println("开始执行还原")
	switch config.GetConfig().FromType {
	case "mysql":
		up_mysql()
	}
	fmt.Println("还原脚本执行完成")
	return ""
}

// 还原MySQL数据库
func up_mysql() {
	fmt.Println("开始执行MySQL还原")
	defer fmt.Println("MySQL还原完成")
	// 获取文件列表
	dir_name := filepath.Dir(fmt.Sprintf("%s_%s.db", config.GetConfig().FileName, time.Now().Format(time.DateOnly)))
	dir, err := os.ReadDir(dir_name)
	if err != nil {
		panic(err)
	}
	for i := 0; i < len(dir); i++ {
		file_name := dir_name + "/" + dir[i].Name()
		if file_name[len(file_name)-2:] != "db" {
			// 如果不是以.db结尾的sqlite数据库文件，就跳过该文件
			continue
		}
		// 打开sqlite数据库
		db, err := gorm.Open(sqlite.Open(file_name))
		if err != nil {
			panic(err)
		}
		maps := []map[string]any{}
		// 获取数据库中的库、表分组
		db.Table("back_table").
			Select("`dns`", "`table`").
			Group("`dns`,`table`").
			Find(&maps)
		for dbs := 0; dbs < len(maps); dbs++ {
			// 匹配对应的MySQL数据库及表结构
			mysql := config.MySql{}
			for temp := 0; temp < len(config.GetConfig().MySQL); temp++ {
				if config.GetConfig().MySQL[temp].Databases == xstring.AString(maps[dbs]["dns"]) {
					mysql = config.GetConfig().MySQL[temp]
				}
			}
			if mysql.Databases == "" {
				continue
			}
			// 配置表信息
			table := config.BackupsConfig{}
			for temp := 0; temp < len(mysql.Backups); temp++ {
				if mysql.Backups[temp].Table == xstring.AString(maps[dbs]["table"]) {
					table = mysql.Backups[temp]
				}
			}
			if table.Table == "" {
				continue
			}
			// 获取备份数据
			lis := []model.BackTable{}
			db.Table("back_table").
				Where("dns", xstring.AString(maps[dbs]["dns"])).
				Where("table", xstring.AString(maps[dbs]["table"])).
				Find(&lis)
			if len(lis) == 0 {
				continue
			}
			fmt.Printf("数据库：%s, 数据表：%s, 恢复条数：%d\n", maps[dbs]["dns"], maps[dbs]["table"], len(lis))
			// 获取MySQL的DNS连接
			con, err := config.GetConnect("mysql", config.GetMysqlDns(mysql))
			if err != nil {
				fmt.Println("数据库连接失败: ", config.GetMysqlDns(mysql))
				panic(err)
			}
			for lis_i := 0; lis_i < len(lis); lis_i++ {
				if lis[lis_i].TableId <= 0 {
					continue
				}
				m := map[string]any{}
				err = json.Unmarshal([]byte(lis[lis_i].TableContent), &m)
				if err != nil {
					fmt.Println("数据转换失败: ", lis[lis_i].TableContent)
					continue
				}
				for m_k, m_v := range m {
					v := xstring.AString(m_v)
					if v == "" {
						continue
					}
					// 如果字符串中存在T、结尾为Z、长度为20，则表示该字符串为时间字符串
					// 2023-06-21T13:22:33Z
					if strings.Contains(v, "T") && v[len(v)-1:] == "Z" && len(v) == 20 {
						m[m_k] = xstring.ToTime(v)
					}
				}
				// 查询条目是否存在，存在就跳过
				var count int64
				con.Table(xstring.AString(maps[dbs]["table"])).Where(table.ID, lis[lis_i].TableId).Count(&count)
				if count > 0 {
					continue
				}
				con.Table(xstring.AString(maps[dbs]["table"])).Create(&m)
			}
		}
	}
}
